<template>
  <div class="editable-tab-content">
    <!-- 编辑模式 -->
    <div v-if="!isPreviewMode" class="editor-input-container">
      <n-scrollbar class="content-scrollbar">
        <n-input
          v-model:value="contentModel"
          type="textarea"
          :placeholder="placeholder"
          class="content-editor"
          :ref="editorRef"
          :disabled="loading"
          :autosize="{ minRows: 20 }"
        />
      </n-scrollbar>
      <!-- 加载遮罩动画 -->
      <div v-if="loading" class="loading-overlay-container">
        <LoadingDots :visible="loading" :message="loadingMessage" />
      </div>
    </div>
    
    <!-- 预览模式 -->
    <div v-else class="preview-container">
      <n-scrollbar class="content-scrollbar">
        <div class="preview-pane" :ref="previewRef">
          <MarkdownRenderer :content="contentModel" />
        </div>
      </n-scrollbar>
      <!-- 加载遮罩动画 -->
      <div v-if="loading" class="loading-overlay-container">
        <LoadingDots :visible="loading" :message="loadingMessage" />
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, watch, nextTick, onUnmounted } from 'vue'
import MarkdownRenderer from '../../shared/components/MarkdownRenderer.vue'
import LoadingDots from '../../shared/components/LoadingDots.vue'

// 定义组件属性
const props = defineProps({
  // 内容
  content: {
    type: String,
    default: ''
  },
  // 是否为预览模式
  isPreviewMode: {
    type: Boolean,
    default: false
  },
  // 是否正在加载
  loading: {
    type: Boolean,
    default: false
  },
  // 加载提示文本
  loadingMessage: {
    type: String,
    default: '正在生成内容'
  },
  // 输入框占位符
  placeholder: {
    type: String,
    default: '请输入内容...'
  }
})

// 定义事件
const emit = defineEmits(['update:content'])

// 创建本地内容模型
const contentModel = ref(props.content)

// 监听外部内容变化
watch(() => props.content, (newContent) => {
  if (newContent !== contentModel.value) {
    contentModel.value = newContent
  }
})

// 监听本地内容变化，发出更新事件
watch(contentModel, (newContent) => {
  emit('update:content', newContent)
})

// 编辑器和预览器引用
const editorRef = ref(null)
const previewRef = ref(null)

// 流式输出状态跟踪
const isStreaming = ref(false)
const lastContentHeight = ref(0)
const scrollCheckTimer = ref(null)

// 监听内容变化，检测是否为流式输出
watch(contentModel, (newContent, oldContent) => {
  // 如果内容长度增加且当前处于加载状态，则认为是流式输出
  if (props.loading && newContent.length > (oldContent?.length || 0)) {
    if (!isStreaming.value) {
      isStreaming.value = true
      startScrollMonitoring()
    }
    // 在流式输出过程中，每次内容变化都调用streamScrollToBottom
    nextTick(() => {
      streamScrollToBottom()
    })
  } else if (!props.loading && isStreaming.value) {
    isStreaming.value = false
    stopScrollMonitoring()
  }
  
  // 无论是否为流式输出，都尝试执行一次自动滚动
  if (props.loading) {
    nextTick(() => {
      checkAndAutoScroll()
    })
  }
})

// 监听加载状态变化
watch(() => props.loading, (newLoading) => {
  if (!newLoading && isStreaming.value) {
    isStreaming.value = false
    stopScrollMonitoring()
  }
})

// 开始滚动监测
const startScrollMonitoring = () => {
  // 清除之前的定时器
  if (scrollCheckTimer.value) {
    clearInterval(scrollCheckTimer.value)
    scrollCheckTimer.value = null
  }
  
  // 设置定时器，定期检查滚动位置
  scrollCheckTimer.value = setInterval(() => {
    checkAndAutoScroll()
  }, 50) // 减少到50ms检查一次，提高响应速度
}

// 停止滚动监测
const stopScrollMonitoring = () => {
  if (scrollCheckTimer.value) {
    clearInterval(scrollCheckTimer.value)
    scrollCheckTimer.value = null
  }
}

// 检查并执行自动滚动
const checkAndAutoScroll = () => {
  let scrollContainer = null
  
  // 获取当前活动的滚动容器
  if (props.isPreviewMode && previewRef.value) {
    // 预览模式下，查找n-scrollbar的容器
    const scrollbarElement = previewRef.value.closest('.content-scrollbar')
    scrollContainer = scrollbarElement?.querySelector('.n-scrollbar-container')
  } else if (!props.isPreviewMode && editorRef.value) {
    // 编辑模式下，查找n-scrollbar的容器
    const scrollbarElement = editorRef.value.$el?.closest('.content-scrollbar')
    scrollContainer = scrollbarElement?.querySelector('.n-scrollbar-container')
  }
  
  // 如果仍然找不到，尝试其他方法
  if (!scrollContainer) {
    if (props.isPreviewMode && previewRef.value) {
      // 预览模式下，查找n-scrollbar的容器
      const parent = previewRef.value.parentElement
      scrollContainer = parent?.querySelector('.n-scrollbar-container') || parent?.querySelector('.n-scrollbar-content')
    } else if (!props.isPreviewMode && editorRef.value) {
      // 编辑模式下，查找n-scrollbar的容器
      const parent = editorRef.value.$el?.parentElement
      scrollContainer = parent?.querySelector('.n-scrollbar-container') || parent?.querySelector('.n-scrollbar-content')
    }
  }
  
  // 如果仍然找不到滚动容器，尝试通过类名直接查找
  if (!scrollContainer) {
    scrollContainer = document.querySelector('.content-scrollbar .n-scrollbar-container') || 
                    document.querySelector('.content-scrollbar .n-scrollbar-content')
  }
  
  if (scrollContainer) {
    // 获取当前滚动位置和总高度
    const scrollHeight = scrollContainer.scrollHeight
    const clientHeight = scrollContainer.clientHeight
    const currentScrollTop = scrollContainer.scrollTop
    
    // 检查内容高度是否发生变化
    if (scrollHeight !== lastContentHeight.value) {
      lastContentHeight.value = scrollHeight
      
      // 计算内容高度与可视高度的比例
      const contentRatio = scrollHeight / clientHeight
      
      // 如果内容高度超过可视高度的50%，则启用自动滚动上移逻辑
      if (contentRatio > 1.5) {
        // 计算当前滚动位置相对于总高度的比例
        const scrollRatio = currentScrollTop / (scrollHeight - clientHeight)
        
        // 如果用户已经滚动到接近底部（距离底部小于100px），则自动滚动
        // 如果内容高度小于可视区域，也自动滚动
        const isNearBottom = scrollHeight - currentScrollTop - clientHeight < 100
        const isContentShorter = scrollHeight <= clientHeight
        
        if (isNearBottom || isContentShorter) {
          // 计算目标滚动位置
          // 当内容高度超过可视高度的50%时，保持底部内容始终可见
          let targetScrollTop = scrollHeight - clientHeight
          
          // 如果内容非常高，则保持底部一定比例的内容可见
          if (contentRatio > 3) {
            // 对于非常长的内容，保持底部30%的内容可见
            targetScrollTop = scrollHeight - (clientHeight * 0.7)
          } else if (contentRatio > 2) {
            // 对于较长的内容，保持底部40%的内容可见
            targetScrollTop = scrollHeight - (clientHeight * 0.6)
          }
          
          // 直接设置滚动位置，不使用平滑滚动，以确保实时性
          scrollContainer.scrollTop = targetScrollTop
        }
      } else {
        // 内容高度不超过可视高度的50%时，使用原来的滚动逻辑
        const isNearBottom = scrollHeight - currentScrollTop - clientHeight < 100
        const isContentShorter = scrollHeight <= clientHeight
        
        if (isNearBottom || isContentShorter) {
          // 直接设置滚动位置，不使用平滑滚动，以确保实时性
          scrollContainer.scrollTop = scrollHeight
        }
      }
    }
  }
}

// 光标定位到开头
const setCursorToStart = () => {
  nextTick(() => {
    if (!editorRef.value) return
    
    const textarea = editorRef.value.$el?.querySelector('textarea')
    if (textarea) {
      textarea.focus()
      textarea.setSelectionRange(0, 0)
    }
  })
}

// 光标定位到结尾
const setCursorToEnd = () => {
  nextTick(() => {
    if (!editorRef.value) return
    
    const textarea = editorRef.value.$el?.querySelector('textarea')
    if (textarea) {
      const length = textarea.value.length
      textarea.focus()
      textarea.setSelectionRange(length, length)
    }
  })
}

// 流式输出专用滚动函数 - 实现与ChatGPT/DeepSeek相似的平滑滚动效果
const streamScrollToBottom = () => {
  nextTick(() => {
    let scrollContainer = null
    
    // 获取当前活动的滚动容器
    if (props.isPreviewMode && previewRef.value) {
      // 预览模式下，查找n-scrollbar的容器
      const scrollbarElement = previewRef.value.closest('.content-scrollbar')
      scrollContainer = scrollbarElement?.querySelector('.n-scrollbar-container')
    } else if (!props.isPreviewMode && editorRef.value) {
      // 编辑模式下，查找n-scrollbar的容器
      const scrollbarElement = editorRef.value.$el?.closest('.content-scrollbar')
      scrollContainer = scrollbarElement?.querySelector('.n-scrollbar-container')
    }
    
    // 如果仍然找不到，尝试其他方法
    if (!scrollContainer) {
      if (props.isPreviewMode && previewRef.value) {
        // 预览模式下，查找n-scrollbar的容器
        const parent = previewRef.value.parentElement
        scrollContainer = parent?.querySelector('.n-scrollbar-container') || parent?.querySelector('.n-scrollbar-content')
      } else if (!props.isPreviewMode && editorRef.value) {
        // 编辑模式下，查找n-scrollbar的容器
        const parent = editorRef.value.$el?.parentElement
        scrollContainer = parent?.querySelector('.n-scrollbar-container') || parent?.querySelector('.n-scrollbar-content')
      }
    }
    
    // 如果仍然找不到滚动容器，尝试通过类名直接查找
    if (!scrollContainer) {
      scrollContainer = document.querySelector('.content-scrollbar .n-scrollbar-container') || 
                      document.querySelector('.content-scrollbar .n-scrollbar-content')
    }
    
    if (scrollContainer) {
      // 获取当前滚动位置和总高度
      const scrollHeight = scrollContainer.scrollHeight
      const clientHeight = scrollContainer.clientHeight
      const currentScrollTop = scrollContainer.scrollTop
      
      // 计算内容高度与可视高度的比例
      const contentRatio = scrollHeight / clientHeight
      
      // 检查用户是否正在手动滚动（通过比较滚动位置）
      // 如果用户滚动位置距离底部超过100px，认为用户正在手动滚动
      const isUserScrolling = scrollHeight - currentScrollTop - clientHeight > 100
      
      // 如果用户正在手动滚动，不自动滚动
      if (isUserScrolling) return
      
      // 判断用户是否正在手动滚动
      const isNearBottom = scrollHeight - currentScrollTop - clientHeight < 150
      const isContentShorter = scrollHeight <= clientHeight
      
      // 如果用户已经滚动到接近底部（距离底部小于150px）或者内容较短，则自动滚动
      if (isNearBottom || isContentShorter) {
        // 计算目标滚动位置
        let targetScrollTop = scrollHeight - clientHeight
        
        // 根据内容高度调整滚动策略，实现类似ChatGPT的自动滚动上移效果
        if (contentRatio > 3) {
          // 对于非常长的内容，保持底部30%的内容可见，避免滚动过快
          targetScrollTop = scrollHeight - (clientHeight * 0.7)
        } else if (contentRatio > 2) {
          // 对于较长的内容，保持底部40%的内容可见
          targetScrollTop = scrollHeight - (clientHeight * 0.6)
        } else if (contentRatio > 1.5) {
          // 对于中等长度的内容，保持底部50%的内容可见
          targetScrollTop = scrollHeight - (clientHeight * 0.5)
        }
        
        // 使用requestAnimationFrame实现平滑滚动，减少滚动时的闪烁
        // 在流式输出时使用'auto'行为，避免动画闪烁
        requestAnimationFrame(() => {
          scrollContainer.scrollTo({
            top: targetScrollTop,
            behavior: 'auto' // 流式输出时使用无动画，避免闪烁
          })
        })
      }
    }
  })
}

// 自动滚动到底部 - 优化版本，实现与ChatGPT相似的自动滚动上移效果
const scrollToBottom = () => {
  nextTick(() => {
    let scrollContainer = null
    
    // 获取当前活动的滚动容器
    if (props.isPreviewMode && previewRef.value) {
      // 预览模式下，查找n-scrollbar的容器
      const scrollbarElement = previewRef.value.closest('.content-scrollbar')
      scrollContainer = scrollbarElement?.querySelector('.n-scrollbar-container')
    } else if (!props.isPreviewMode && editorRef.value) {
      // 编辑模式下，查找n-scrollbar的容器
      const scrollbarElement = editorRef.value.$el?.closest('.content-scrollbar')
      scrollContainer = scrollbarElement?.querySelector('.n-scrollbar-container')
    }
    
    // 如果仍然找不到，尝试其他方法
    if (!scrollContainer) {
      if (props.isPreviewMode && previewRef.value) {
        // 预览模式下，查找n-scrollbar的容器
        const parent = previewRef.value.parentElement
        scrollContainer = parent?.querySelector('.n-scrollbar-container') || parent?.querySelector('.n-scrollbar-content')
      } else if (!props.isPreviewMode && editorRef.value) {
        // 编辑模式下，查找n-scrollbar的容器
        const parent = editorRef.value.$el?.parentElement
        scrollContainer = parent?.querySelector('.n-scrollbar-container') || parent?.querySelector('.n-scrollbar-content')
      }
    }
    
    // 如果仍然找不到滚动容器，尝试通过类名直接查找
    if (!scrollContainer) {
      scrollContainer = document.querySelector('.content-scrollbar .n-scrollbar-container') || 
                      document.querySelector('.content-scrollbar .n-scrollbar-content')
    }
    
    if (scrollContainer) {
      // 获取当前滚动位置和总高度
      const scrollHeight = scrollContainer.scrollHeight
      const clientHeight = scrollContainer.clientHeight
      const currentScrollTop = scrollContainer.scrollTop
      
      // 计算内容高度与可视高度的比例
      const contentRatio = scrollHeight / clientHeight
      
      // 如果内容高度超过可视高度的50%，则启用自动滚动上移逻辑
      if (contentRatio > 1.5) {
        // 计算当前滚动位置相对于总高度的比例
        const scrollRatio = currentScrollTop / (scrollHeight - clientHeight)
        
        // 如果用户已经滚动到接近底部（距离底部小于100px），则自动滚动
        // 如果内容高度小于可视区域，也自动滚动
        const isNearBottom = scrollHeight - currentScrollTop - clientHeight < 100
        const isContentShorter = scrollHeight <= clientHeight
        
        if (isNearBottom || isContentShorter) {
          // 计算目标滚动位置
          // 当内容高度超过可视高度的50%时，保持底部内容始终可见
          let targetScrollTop = scrollHeight - clientHeight
          
          // 如果内容非常高，则保持底部一定比例的内容可见
          if (contentRatio > 3) {
            // 对于非常长的内容，保持底部30%的内容可见
            targetScrollTop = scrollHeight - (clientHeight * 0.7)
          } else if (contentRatio > 2) {
            // 对于较长的内容，保持底部40%的内容可见
            targetScrollTop = scrollHeight - (clientHeight * 0.6)
          }
          
          // 使用平滑滚动效果，增加滚动速度
          scrollContainer.scrollTo({
            top: targetScrollTop,
            behavior: 'smooth'
          })
        }
      } else {
        // 内容高度不超过可视高度的50%时，使用原来的滚动逻辑
        const isNearBottom = scrollHeight - currentScrollTop - clientHeight < 100
        const isContentShorter = scrollHeight <= clientHeight
        
        if (isNearBottom || isContentShorter) {
          // 使用平滑滚动效果，增加滚动速度
          scrollContainer.scrollTo({
            top: scrollHeight,
            behavior: 'smooth'
          })
        }
      }
    }
  })
}

// 暴露引用和方法给父组件
defineExpose({
  editorRef,
  previewRef,
  setCursorToStart,
  setCursorToEnd,
  scrollToBottom,
  streamScrollToBottom
})

// 组件卸载时清理定时器
onUnmounted(() => {
  stopScrollMonitoring()
})
</script>

<style scoped>
.editable-tab-content {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  position: relative;
  overflow: hidden; /* 确保内容不会溢出 */
}

.editor-input-container,
.preview-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  position: relative;
  overflow: hidden; /* 确保内容不会溢出 */
}

.content-scrollbar {
  height: 100%;
  flex: 1;
  min-height: 0;
  width: 100%;
}

.content-editor {
  height: 100%;
  flex: 1;
  min-height: 0;
  width: 100%;
}

.preview-pane {
  padding: 20px;
  height: 100%;
  overflow-y: auto;
  line-height: 1.8;
  font-size: 14px;
  color: var(--n-text-color);
  background-color: var(--n-color);
  border-radius: var(--n-border-radius);
  width: 100%;
  box-sizing: border-box;
}

/* 加载遮罩容器样式 */
.loading-overlay-container {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(3px);
  z-index: 1000;
  border-radius: var(--n-border-radius);
}

/* 确保输入框占满高度 */
:deep(.n-input) {
  height: 100% !important;
  display: flex !important;
  flex-direction: column !important;
  width: 100% !important;
}

:deep(.n-input__textarea) {
  flex: 1 !important;
  min-height: 0 !important;
  height: 100% !important;
  width: 100% !important;
}

:deep(.n-input__textarea-el) {
  height: 100% !important;
  min-height: 100% !important;
  resize: none !important;
  width: 100% !important;
  box-sizing: border-box !important;
}

/* 确保滚动条占满高度 */
:deep(.n-scrollbar) {
  height: 100% !important;
  width: 100% !important;
}

:deep(.n-scrollbar-container) {
  height: 100% !important;
  width: 100% !important;
}

:deep(.n-scrollbar-content) {
  height: 100% !important;
  width: 100% !important;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .preview-pane {
    padding: 16px;
    line-height: 1.7;
  }
  
  .content-editor :deep(.n-input__textarea-el) {
    padding: 12px;
  }
}
</style>